home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / NLProc.c < prev    next >
Text File  |  1995-01-04  |  10KB  |  275 lines

  1. /* NLProc.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "NLProc.h"
  31. #include "FastFixedPoint.h"
  32. #include "SampleConsts.h"
  33. #include "NonlinearProcSpec.h"
  34. #include "Memory.h"
  35. #include "WaveTableObject.h"
  36. #include "AlgoWaveTableObject.h"
  37. #include "FloatingPoint.h"
  38. #include "WaveIndexUtility.h"
  39.  
  40.  
  41. struct NLProcRec
  42.     {
  43.         /* number of frames per table */
  44.         long                                        FramesPerTable;
  45.         /* number of tables */
  46.         long                                        NumberOfTables;
  47.         /* raw wave table data array */
  48.         void**                                    WaveTableMatrix;
  49.         /* function for indexing the wave table */
  50.         signed long                            (*WaveIndexer)(float Phase, FastFixedType TableIndex,
  51.                                                             long NumTables, long Frames, void** Matrix);
  52.         /* stereo flag */
  53.         MyBoolean                                StereoFlag;
  54.         /* number of bits */
  55.         NumBitsType                            NumBits;
  56.         /* reciprocal of volume scaling factor */
  57.         float                                        InverseVolume;
  58.  
  59.         /* state parameters */
  60.         float                                        CurrentInputScaling;
  61.         float                                        CurrentOutputScaling;
  62.         FastFixedType                        CurrentWaveTableIndex;
  63.  
  64.         /* control parameters */
  65.         float                                        InputScaling;
  66.         float                                        InputAccent1;
  67.         float                                        InputAccent2;
  68.         float                                        InputAccent3;
  69.         float                                        InputAccent4;
  70.         float                                        OutputScaling;
  71.         float                                        OutputAccent1;
  72.         float                                        OutputAccent2;
  73.         float                                        OutputAccent3;
  74.         float                                        OutputAccent4;
  75.         float                                        WaveTableIndex;
  76.         float                                        IndexAccent1;
  77.         float                                        IndexAccent2;
  78.         float                                        IndexAccent3;
  79.         float                                        IndexAccent4;
  80.  
  81.         /* free list link */
  82.         NLProcRec*                            Next;
  83.     };
  84.  
  85.  
  86. static NLProcRec*                NLProcFreeList = NIL;
  87.  
  88.  
  89. /* flush free list elements */
  90. void                            FlushCachedNLProcStuff(void)
  91.     {
  92.         while (NLProcFreeList != NIL)
  93.             {
  94.                 NLProcRec*            Temp;
  95.  
  96.                 Temp = NLProcFreeList;
  97.                 NLProcFreeList = NLProcFreeList->Next;
  98.                 ReleasePtr((char*)Temp);
  99.             }
  100.     }
  101.  
  102.  
  103. /* create a new nonlinear processor */
  104. NLProcRec*                NewNLProcProcessor(struct NonlinProcSpecRec* Template,
  105.                                         MyBoolean StereoFlag, float InverseVolume)
  106.     {
  107.         NLProcRec*            NLProc;
  108.  
  109.         CheckPtrExistence(Template);
  110.         if (NLProcFreeList != NIL)
  111.             {
  112.                 NLProc = NLProcFreeList;
  113.                 NLProcFreeList = NLProcFreeList->Next;
  114.             }
  115.          else
  116.             {
  117.                 NLProc = (NLProcRec*)AllocPtrCanFail(sizeof(NLProcRec),"NLProcRec");
  118.                 if (NLProc == NIL)
  119.                     {
  120.                      FailurePoint1:
  121.                         return NIL;
  122.                     }
  123.             }
  124.         NLProc->InverseVolume = InverseVolume;
  125.         switch (GetNLProcSpecWaveType(Template))
  126.             {
  127.                 default:
  128.                     EXECUTE(PRERR(ForceAbort,"NewNLProcProcessor:  invalid nlproc wavetable type"));
  129.                     break;
  130.                 case eNLDataWaveTable:
  131.                     {
  132.                         WaveTableObjectRec*                DataWaveTable;
  133.                         long                                            Index;
  134.  
  135.                         DataWaveTable = GetNLProcSpecDataWaveTable(Template);
  136.                         CheckPtrExistence(DataWaveTable);
  137.                         NLProc->NumberOfTables = WaveTableObjectGetNumTables(DataWaveTable);
  138.                         NLProc->FramesPerTable = WaveTableObjectEntriesPerTable(DataWaveTable);
  139.                         NLProc->NumBits = WaveTableObjectGetNumBits(DataWaveTable);
  140.                         NLProc->WaveTableMatrix = (void**)AllocPtrCanFail(sizeof(void*)
  141.                             * NLProc->NumberOfTables,"Wave table vector");
  142.                         if (NLProc->WaveTableMatrix == NIL)
  143.                             {
  144.                              FailurePoint2:
  145.                                 ReleasePtr((char*)NLProc);
  146.                                 goto FailurePoint1;
  147.                             }
  148.                         for (Index = 0; Index < NLProc->NumberOfTables; Index += 1)
  149.                             {
  150.                                 PRNGCHK(NLProc->WaveTableMatrix,&(((void**)(NLProc->WaveTableMatrix))[
  151.                                     Index]),sizeof(((void**)(NLProc->WaveTableMatrix))[Index]));
  152.                                 ((void**)(NLProc->WaveTableMatrix))[Index]
  153.                                     = WaveTableObjectGetRawSlice(DataWaveTable,Index);
  154.                             }
  155.                     }
  156.                     break;
  157.                 case eNLAlgoWaveTable:
  158.                     {
  159.                         AlgoWaveTableObjectRec*        AlgoWaveTable;
  160.                         long                                            Index;
  161.  
  162.                         AlgoWaveTable = GetNLProcSpecAlgoWaveTable(Template);
  163.                         CheckPtrExistence(AlgoWaveTable);
  164.                         NLProc->NumberOfTables = AlgoWaveTableObjectGetNumTables(AlgoWaveTable);
  165.                         NLProc->FramesPerTable = AlgoWaveTableObjectGetNumFrames(AlgoWaveTable);
  166.                         NLProc->NumBits = AlgoWaveTableObjectGetNumBits(AlgoWaveTable);
  167.                         NLProc->WaveTableMatrix = (void**)AllocPtrCanFail(sizeof(void*)
  168.                             * NLProc->NumberOfTables,"Wave table vector");
  169.                         if (NLProc->WaveTableMatrix == NIL)
  170.                             {
  171.                              FailurePoint2a:
  172.                                 goto FailurePoint2;
  173.                             }
  174.                         for (Index = 0; Index < NLProc->NumberOfTables; Index += 1)
  175.                             {
  176.                                 PRNGCHK(NLProc->WaveTableMatrix,&(((void**)(NLProc->WaveTableMatrix))[
  177.                                     Index]),sizeof(((void**)(NLProc->WaveTableMatrix))[Index]));
  178.                                 ((void**)(NLProc->WaveTableMatrix))[Index]
  179.                                     = AlgoWaveTableObjectGetRawSlice(AlgoWaveTable,Index);
  180.                             }
  181.                     }
  182.                     break;
  183.             }
  184.         switch (NLProc->NumBits)
  185.             {
  186.                 default:
  187.                     EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad num bits"));
  188.                     break;
  189.                 case eSample8bit:
  190.                     NLProc->WaveIndexer = (signed long (*)(float,
  191.                         FastFixedType,long,long,void**))&WaveTable8Bit;
  192.                     break;
  193.                 case eSample16bit:
  194.                     NLProc->WaveIndexer = (signed long (*)(float,
  195.                         FastFixedType,long,long,void**))&WaveTable16Bit;
  196.                     break;
  197.             }
  198.         NLProc->StereoFlag = StereoFlag;
  199.         NLProc->InputScaling = GetNLProcInputScaling(Template);
  200.         NLProc->InputAccent1 = GetNLProcInputAccent1(Template);
  201.         NLProc->InputAccent2 = GetNLProcInputAccent2(Template);
  202.         NLProc->InputAccent3 = GetNLProcInputAccent3(Template);
  203.         NLProc->InputAccent4 = GetNLProcInputAccent4(Template);
  204.         NLProc->OutputScaling = GetNLProcOutputScaling(Template);
  205.         NLProc->OutputAccent1 = GetNLProcOutputAccent1(Template);
  206.         NLProc->OutputAccent2 = GetNLProcOutputAccent2(Template);
  207.         NLProc->OutputAccent3 = GetNLProcOutputAccent3(Template);
  208.         NLProc->OutputAccent4 = GetNLProcOutputAccent4(Template);
  209.         NLProc->WaveTableIndex = GetNLProcWaveTableIndex(Template);
  210.         NLProc->IndexAccent1 = GetNLProcIndexAccent1(Template);
  211.         NLProc->IndexAccent2 = GetNLProcIndexAccent2(Template);
  212.         NLProc->IndexAccent3 = GetNLProcIndexAccent3(Template);
  213.         NLProc->IndexAccent4 = GetNLProcIndexAccent4(Template);
  214.         return NLProc;
  215.     }
  216.  
  217.  
  218. /* dispose of the nonlinear processor */
  219. void                            DisposeNLProcProcessor(NLProcRec* NLProc)
  220.     {
  221.         CheckPtrExistence(NLProc);
  222.         ReleasePtr((char*)NLProc->WaveTableMatrix);
  223.         NLProc->Next = NLProcFreeList;
  224.         NLProcFreeList = NLProc;
  225.     }
  226.  
  227.  
  228. /* update nonlinear state with accent information */
  229. void                            UpdateNLProcState(NLProcRec* NLProc, float Accent1, float Accent2,
  230.                                         float Accent3, float Accent4)
  231.     {
  232.         float                        Temp;
  233.  
  234.         CheckPtrExistence(NLProc);
  235.         /* multiply by NLProc->InverseVolume to undo the division everyone else does */
  236.         NLProc->CurrentInputScaling = (NLProc->InputScaling + Accent1 * NLProc->InputAccent1
  237.             + Accent2 * NLProc->InputAccent2 + Accent3 * NLProc->InputAccent3
  238.             + Accent4 * NLProc->InputAccent4) * NLProc->InverseVolume;
  239.         /* divide by NLProc->InverseVolume to restore the correct volume, and by */
  240.         /* MAX16BIT to correct for value returned from wave index routine */
  241.         NLProc->CurrentOutputScaling = (NLProc->OutputScaling + Accent1 * NLProc->OutputAccent1
  242.             + Accent2 * NLProc->OutputAccent2 + Accent3 * NLProc->OutputAccent3
  243.             + Accent4 * NLProc->OutputAccent4) / (NLProc->InverseVolume * MAX16BIT);
  244.         Temp = NLProc->WaveTableIndex + Accent1 * NLProc->IndexAccent1
  245.             + Accent2 * NLProc->IndexAccent2 + Accent3 * NLProc->IndexAccent3
  246.             + Accent4 * NLProc->IndexAccent4;
  247.         NLProc->CurrentWaveTableIndex = Double2FastFixed(Temp);
  248.     }
  249.  
  250.  
  251. /* apply nonlinear processing to some stuff */
  252. void                            ApplyNLProc(largefixedsigned* Data, long NumFrames, NLProcRec* NLProc)
  253.     {
  254.         long                        Scan;
  255.  
  256.         CheckPtrExistence(Data);
  257.         CheckPtrExistence(NLProc);
  258.         if (NLProc->StereoFlag)
  259.             {
  260.                 NumFrames *= 2;
  261.             }
  262.         for (Scan = 0; Scan < NumFrames; Scan += 1)
  263.             {
  264.                 float                        Temp;
  265.  
  266.                 PRNGCHK(Data,&(Data[Scan]),sizeof(Data[Scan]));
  267.                 Temp = (*NLProc->WaveIndexer)((1 + largefixed2single(Data[Scan])
  268.                     * NLProc->CurrentInputScaling) / 2 * (NLProc->FramesPerTable - 1),
  269.                     NLProc->CurrentWaveTableIndex,NLProc->NumberOfTables,
  270.                     NLProc->FramesPerTable,NLProc->WaveTableMatrix)
  271.                     * NLProc->CurrentOutputScaling;
  272.                 Data[Scan] = double2largefixed(Temp);
  273.             }
  274.     }
  275.